<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>类的基本知识</title>
</head>
<body>
  <script type="text/javascript">
  /*
    总结：
      1. 类中的构造器不是必须写的，要对实例进行一些初始化的操作，如添加指定属性时才写。
      2. 如果A类继承了B类，且A类中写了构造器，那么A类构造器中的super是必须要调用的。
      3. 类中所定义的方法，都是放在了类的原型对象上，供实例去使用。
  */
    // 创建一个Person类 
    class Person {
      // 构造器方法
      constructor(name, age) {
        // 构造器中的this是谁？—— 类的实例对象
        this.name = name
        this.age = age
      }
      // 一般方法 
      speak() {
        // speak方法放在了哪里？—— 类的原型对象上，供实例使用
        // **通过Person实例调用speak时，speak中的this就是Person实例**
        console.log(this)
        console.log(`我叫${this.name}, 我的年龄是${this.age}`)
      }
    }
    // 创建一个Person的实例对象
    // const p1 = new Person('tom', 18)
    // const p2 = new Person('jerry', 19)
    // p1.speak()
    // p2.speak()
    // p1.speak.call({name:1, age:2})
    // console.log(p1, p2)

    // 创建一个Student类，继承于Person类
    class Student extends Person {
      constructor(name, age, grade) {
        super(name, age)
        this.grade = grade
      }
      speak() {
        console.log(this)
        console.log(`我叫${this.name}, 我的年龄是${this.age}，我读的是${this.grade}年级`)
      }
      study() {
        // study方法放在了哪里？—— 类的原型对象上，供实例使用
        // **通过Student实例调用study时，study中的this就是Student实例**
        console.log('努力学习')
      }
    }
    const s1 = new Student('小张', 15, '一年级')
    s1.speak()
    console.log(s1)

    class Car {
      constructor(name, price) {
        this.name = name
        this.price = price
        // this.wheel = 4
      }
      // 类中可以直接写赋值语句，如下代码的含义是：给Car的实例对象添加一个属性，名为a，值为1
      a = 1
      wheel = 4
      static demo = 100
    }
    // Car.demo = 100

    const c1 = new Car('奔驰c63', 199)
    const c2 = new Car('宝马', 299)
    console.log(c1)
    console.log(c2)
  </script>
</body>
</html>